home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr47
/
rxdoscmd.zip
/
RXDOSCPY.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-06-06
|
29KB
|
695 lines
TITLE 'Copy - RxDOS Command Shell Copy'
PAGE 59, 132
.LALL
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; RxDOS Command Shell Copy ;
;...............................................................;
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Real Time Dos ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; This material was created as a published version of a DOS ;
; equivalent product. This program logically functions in ;
; the same way as MSDOS functions and it is internal data ;
; structure compliant with MSDOS 5.0 ;
; ;
; This product is distributed AS IS and contains no warranty ;
; whatsoever, including warranty of merchantability or ;
; fitness for a particular purpose. ;
; ;
; ;
; (c) Copyright 1990, 1992. Api Software and Mike Podanoffsky ;
; All Rights Reserved Worldwide. ;
; ;
; This product is protected under copyright laws and may not ;
; be reproduced in whole or in part, in any form or media, ;
; included but not limited to source listing, facimilie, data ;
; transmission, cd-rom, or floppy disk without the expressed ;
; written consent of the author. ;
; ;
; Licence for distribution in commercial use: ;
; ;
; Api Software ;
; 12 South Walker Street ;
; Lowell, MA 01851 ;
; 508/ 454-4961. ;
; ;
;...............................................................;
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; RxDOS Command Shell ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Programmer's Notes: ;
; ;
; Command Shell consists of two parts bound together into a ;
; single executable load. There exists a single resident ;
; command shell which is accessible by an Int 2Eh. ;
; ;
;...............................................................;
include rxdosmac.asm
include rxdosdef.asm
include rxdoscin.asm
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; RxDOS Command Shell ;
;...............................................................;
RxDOSCMD SEGMENT PUBLIC 'CODE'
assume cs:RxDOSCMD, ds:RxDOSCMD, es:RxDOSCMD, ss:RxDOSCMD
public _Copy
extrn CmndError_BadSwitch : near
extrn CmndError_CannotCopyUntoSelf : near
extrn CmndError_CannotCreateFile : near
extrn CmndError_ContentsLostBeforeCopy : near
extrn CmndError_FileNotFound : near
extrn CountArgs : near
extrn CRLF : near
extrn deleteArg : near
extrn DisplayError : near
extrn DisplayErrorMessage : near
extrn DisplayLine : near
extrn RxDOS_DTA : near
extrn RxDOS_AllFiles : near
extrn _AppendPathName : near
extrn _CopyString : near
extrn _Copy_FilesCopied : near
extrn _CmndParse_Break : near
extrn _lowerCase : near
extrn _SwitchChar : near
extrn _splitpath : near
extrn _makePath : near
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Copy filenameA+filenameB+filenameC filenameDest ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Usage: ;
; ss:di Arg Array ;
; ax Number of arguments in array ;
;...............................................................;
_Copy:
Entry
def __argarray, di ; args array
def __numArgs, ax ; # args
def __Mode, 0000 ; non-z if ascii/ z if binary
def __AddMode ; 0000 not add mode
def __NextAddMode ; 0000 next is add mode
def _endoffile
def _filesCopies, 0000
def _srcHandle , 0000
def _destHandle , 0000
ddef _destCluster
ddef _srcCluster
defbytes _destFilename , 130
defbytes _createFilename, 130
defbytes _copyFilename , 130
defbytes _buffer, 128
_tempFilename = _copyFilename ; equate temp filename
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; get/test destination filename
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cmp ax, 2 ; must have at least two args
ifc _copyError ; any less means error -->
dec ax
add ax, ax ; args offset in words
add di, ax ; point to last arg
push word ptr [ di ] ; get last arg address
call deleteArg
pop si
lea di, offset [ _tempFilename ][ bp ]
call _copyArgument ; copy argument
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; see if dest is just a directory name
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mov cx, ATTR_DIRECTORY
lea dx, offset [ _tempFilename ][ bp ]
Int21 FindFirstFile ; locate file with name
jc _Copy_18 ; not a directory -->
; if . or .. handle special
_Copy_08:
test byte ptr [ RxDOS_DTA. findFileAttribute ], ATTR_DIRECTORY
jz _Copy_18 ; if not a dir entry -->
cmp byte ptr [ RxDOS_DTA. findFileName ], '.'
jnz _Copy_24 ; if dir and not . or .. -->
Int21 FindNextFile ; locate next file
jnc _Copy_08 ; see if also a dir -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; scan name for just directory
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_Copy_18:
lea di, offset [ _tempFilename ][ bp ]
_Copy_20:
cmp byte ptr [ di ], 00 ; null ?
jz _Copy_26 ; yes, done -->
inc di
cmp byte ptr [ di-1 ], ':' ; only drive /colon entered ?
jnz _Copy_20 ; no -->
cmp byte ptr [ di ], 00 ;
jnz _Copy_26
_Copy_24:
mov si, offset RxDOS_AllFiles ; dummy path
call _AppendPathName ; append all files
_Copy_26:
lea si, offset [ _tempFilename ][ bp ]
lea di, offset [ _destFilename ][ bp ] ; expansion area
mov byte ptr [ di ], '\' ; (in case no output generated)
Int21 GetActualFileName ; expand name
ifc _copyError ; destination doesn't exist -->
xor ax, ax
mov cx, 4
lea di, offset [ _destCluster ][ bp ] ; clusters
rep stosw ; clear clusters
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; main loop through all args
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_Copy_30:
mov word ptr [ __AddMode ][ bp ], 0000 ; not add mode
mov word ptr [ __NextAddMode ][ bp ], 0000 ; next is not add mode
_Copy_32:
mov di, word ptr [ __argarray ][ bp ] ; get arg pointer to next arg
mov si, word ptr [ di ] ; point to text
or si, si ; null entry ?
ifz _Copy_Return ; yes, return -->
add word ptr [ __argarray ][ bp ], 2 ; skip this argument next time
mov al, byte ptr [ si ]
cmp al, byte ptr [ _SwitchChar ] ; switch ?
ifz _Copy_TestSwitch ; yes, go test switch -->
cmp al, '+'
ifz _Copy_AddMode ; set add mode -->
lea di, offset [ _copyFilename ][ bp ]
call _copyArgument
call _scanForwardArgArray ; see if followed by +
mov word ptr [ __NextAddMode ][ bp ], ax ; next add mode
mov dx, di ; copy filename
mov cx, ATTR_NORMAL
Int21 FindFirstFile ; locate file with name
jnc _Copy_36 ; if file found -->
mov dx, offset CmndError_FileNotFound
call DisplayLine
jmp _copyErrorCleanUp
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; open source file
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_Copy_36:
lea di, offset [ _copyFilename ][ bp ]
call _replaceWithRealName
Int21 OpenFile, OPEN_ACCESS_READONLY
storarg _srcHandle, ax
ifc _copyError
mov bx, ax
call GetClusterValue ; src cluster
mov word ptr [ _srcCluster. _low ][ bp ], ax ; (cluster)
mov word ptr [ _srcCluster. _high ][ bp ], dx ; (drive )
jz _Copy_44 ; if not a file -->
call _compareClusters
jnz _Copy_44 ; no -->
; error: file destroyed
mov dx, offset CmndError_ContentsLostBeforeCopy
call DisplayErrorMessage
jmp _copyErrorCleanUp
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; attempt create file
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_Copy_44:
getarg bx, _destHandle
or bx, bx ; any dest file ?
jz _Copy_48 ; no, MUST create -->
cmp word ptr [ __AddMode ][ bp ], 0000 ; add mode ?
jnz _Copy_56 ; yes, append to existing file -->
_Copy_48:
lea si, offset [ _destFilename ][ bp ] ; destination filename
lea di, offset [ _createFilename ][ bp ] ; make destination name
call _CopyString ; copy string
lea di, offset [ _createFilename ][ bp ] ; make destination name
call _makeUniqueName ; make unique name
lea dx, offset [ _createFilename ][ bp ] ; destination filename
Int21 OpenFile, OPEN_ACCESS_READONLY ; we'll try open first
jc _Copy_52 ; MUST create -->
mov bx, ax
call GetClusterValue ; cluster of dest
mov word ptr [ _destCluster. _low ][ bp ], ax ; (cluster)
mov word ptr [ _destCluster. _high ][ bp ], dx ; (drive )
Int21 CloseFile ; release file
call _compareClusters
jnz _Copy_52 ; if not same files -->
mov dx, offset CmndError_CannotCopyUntoSelf
call DisplayErrorMessage
jmp _copyErrorCleanUp
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; create file
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_Copy_52:
mov cx, ATTR_NORMAL
lea dx, offset [ _createFilename ][ bp ] ; destination filename
Int21 CreateFile ; this is wrong (must try open first)
storarg _destHandle, ax
ifc _copyError
mov bx, ax
call GetClusterValue ; cluster of dest
mov word ptr [ _destCluster. _low ][ bp ], ax ; (cluster)
mov word ptr [ _destCluster. _high ][ bp ], dx ; (drive )
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; display filename
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_Copy_56:
mov word ptr [ _endoffile ][ bp ], 0000
getarg bx, _srcHandle
Int21 IoControl, 0000 ; is source a char device ?
test dx, DEV_CHAR ; test device flag
jz _Copy_62 ; if file, display filename -->
storarg __Mode, 01 ; else switch to ascii mode
jmp short _Copy_66
_Copy_62:
mov dx, offset [ RxDOS_DTA. findFileName ]
call DisplayLine ; display line
call CRLF ; cr/lf
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; copy loop
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_Copy_66:
mov cx, 128
getarg bx, _srcHandle
lea dx, offset [ _buffer ][ bp ]
Int21 ReadFile ; read
ifc _copyDisplayError ; if error -->
or ax, ax ; end of file ?
jz _Copy_78 ; yes, all done -->
mov cx, ax ; how many bytes actually read
cmp word ptr [ __Mode ][ bp ], 0000 ; ascii mode ?
jz _Copy_70 ; no -->
push cx
mov al, 'Z'-40h
lea di, offset [ _buffer ][ bp ]
repnz scasb ; scan buffer for ^Z
pop cx
jnz _Copy_70 ; if ^z not located ->
mov word ptr [ _endoffile ][ bp ], -1 ; set end of file mode
dec cx ; don't copy ^Z
_Copy_70:
or cx, cx ; any more to copy ?
jz _Copy_78 ; no more -->
getarg bx, _destHandle
lea dx, offset [ _buffer ][ bp ]
Int21 WriteFile
cmp word ptr [ _endoffile ][ bp ], 0000 ; end of file ?
jz _Copy_66 ; not end of file yet -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; close source file
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_Copy_78:
getarg bx, _srcHandle
Int21 CloseFile
storarg _srcHandle, 0000
cmp word ptr [ __NextAddMode ][ bp ], 0000 ; is next add mode ?
jnz _Copy_82
getarg bx, _destHandle
Int21 CloseFile ; if no adds left ...
storarg _destHandle, 0000
Int21 FindNextFile ; see if more files to copy
ifnc _Copy_36 ; if file found -->
_Copy_82:
jmp _Copy_30
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; return
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_Copy_Return:
inc word ptr [ _filesCopies ][ bp ] ; # files copied.
_Copy_ReturnClose:
getarg bx, _destHandle
cmp bx, 5
jle _Copy_ReturnClose_08
Int21 CloseFile ; close last file
_Copy_ReturnClose_08:
Return
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; add mode
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_Copy_AddMode:
mov word ptr [ __AddMode ][ bp ], -1 ; set add mode
jmp _Copy_32
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; test switches
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_Copy_TestSwitch:
mov al, byte ptr [ si+1 ]
call _lowerCase ; test switch option
goto 'a', _copyAsciiSwitch
goto 'b', _copyBinarySwitch
push ax
mov dx, offset CmndError_BadSwitch
call DisplayLine ; show error message
pop dx
call DisplayLine ; show arg
Return
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; if ascii switch
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_copyAsciiSwitch:
storarg __Mode, 01 ; ascii mode
jmp _Copy_32
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; if binary switch
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_copyBinarySwitch:
storarg __Mode, 00 ; binary mode
jmp _Copy_32
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; error in rename command
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_copyDisplayError:
call DisplayError
jmp _copyErrorCleanUp
_copyError:
mov dx, offset CmndError_CannotCreateFile
call DisplayErrorMessage
_copyErrorCleanUp:
getarg bx, _destHandle
or bx, bx ; if not assigned,
jz _copyErrorCleanUp_08 ; don't delete -->
Int21 CloseFile ; close last file
_copyErrorCleanUp_08:
Return
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Copy Argument ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Usage: ;
; si points to argument start ;
; di points to destination ;
;...............................................................;
_copyArgument:
push di
_copyArgument_06:
lodsb ; get character
stosb
cmp al, ' '+1 ; space or control character ?
jc _copyArgument_10 ; yes -->
cmp al, byte ptr [ _SwitchChar ] ; switch character ?
jz _copyArgument_10 ; yes -->
call _CmndParse_Break ; parse break ?
jnz _copyArgument_06 ; no, go to next char -->
_copyArgument_10:
mov byte ptr [ di-1 ], 0 ; place null terminator
pop di
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; LookAhead Add Mode ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Usage: ;
; si points to argument start ;
; di points to destination ;
;...............................................................;
_scanForwardArgArray:
push di
mov di, word ptr [ __argarray ][ bp ] ; get arg pointer to next arg
xor ax, ax ; next is NOT add
_scanForwardArgArray_10:
mov si, word ptr [ di ] ; point to text
or si, si ; null entry ?
jz _scanForwardArgArray_12 ; yes, return -->
add di, 2
cmp byte ptr [ si ], '/'
jz _scanForwardArgArray_10
cmp byte ptr [ si ], '+'
jnz _scanForwardArgArray_12
mov ax, -1 ; next IS add
_scanForwardArgArray_12:
pop di
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Get Starting Cluster Value for a given Handle ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; bx file handle ;
; ;
; Output: ;
; ax starting cluster value ;
;...............................................................;
GetClusterValue:
push es
push di
push bx
Int21 GetPSPAddress ; returns bx with segment
mov es, bx ; set PSP address
pop si ; restore handle offset
push si ; (save handle)
les bx, dword ptr es:[ pspFileHandlePtr ] ; point to file handles
mov bl, byte ptr es:[ bx + si ] ; get real sft offset
xor bh, bh
mov ax, 1216h
int 2fh ; UNDOCUMENTED DOS CALL
mov ax, word ptr es:[ sftBegCluster ][ di ]
mov dx, word ptr es:[ sftDevInfo ][ di ]
and dx, sftDrivemask
pop bx
pop di
pop es
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Compare Drive/Cluster Info ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; NZ if not equal ;
;...............................................................;
_compareClusters:
cmp word ptr [ _destCluster. _low ][ bp ], 0000
jnz _compareClusters_NotEqual
cmp word ptr [ _srcCluster. _low ][ bp ], 0000
jnz _compareClusters_NotEqual
mov ax, word ptr [ _destCluster. _low ][ bp ] ; (cluster)
cmp ax, word ptr [ _srcCluster. _low ][ bp ]
jnz _compareClusters_NotEqual
mov ax, word ptr [ _destCluster. _high ][ bp ] ; (drive )
cmp ax, word ptr [ _srcCluster. _high ][ bp ]
jnz _compareClusters_NotEqual
ret
_compareClusters_NotEqual:
mov ax, -1
or ax, ax
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Make Unique Name ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Usage: ;
; di name expected with wild characters ;
;...............................................................;
_makeUniqueName:
Entry
def _name, di
defbytes _expandedname, sizeExpandedName
push di
mov si, di
lea di, offset [ _expandedname ][ bp ]
call _splitpath
mov cx, 8
mov si, offset [ RxDOS_DTA. findFileName ]
lea di, offset [ _expandedname. expFilename ][ bp ]
call _makeReplacement
inc si
mov cx, 3
lea di, offset [ _expandedname. expExtension + 1 ][ bp ]
call _makeReplacement
lea si, offset [ _expandedname ][ bp ]
getarg di, _name
call _makePath
pop di
mov dx, di
Return
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Make Replacement ;
;...............................................................;
_makeReplacement:
cmp byte ptr [ di ], '?'
jnz _makeReplacement_08
mov al, byte ptr [ si ]
mov byte ptr [ di ], al
_makeReplacement_08:
inc di
inc si
cmp byte ptr [ si ], '.'
jz _makeReplacement_12
cmp byte ptr [ si ], 00
jz _makeReplacement_12
loop _makeReplacement
_makeReplacement_12:
mov byte ptr [ di ], 00
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Replace with Real Name ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Usage: ;
; di full expanded name expected ;
;...............................................................;
_replaceWithRealName:
push di
mov dx, di
_replaceWithRealName_04:
cmp byte ptr [ di ], 0 ; find end of string
jz _replaceWithRealName_08
inc di
jmp _replaceWithRealName_04
_replaceWithRealName_08:
cmp dx, di
jz _replaceWithRealName_12
mov al, byte ptr [ di-1 ]
cmp al, ':'
jz _replaceWithRealName_12
cmp al, '\'
jz _replaceWithRealName_12
dec di
jmp _replaceWithRealName_08
_replaceWithRealName_12:
mov si, offset [ RxDOS_DTA. findFileName ] ; expanded name
call _CopyString
pop di
mov dx, di
ret
RxDOSCMD ENDS
END